/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>

#include "yaffut.h"

#include "myassert.h"
#include "Commands.h"
#include "Utils.h"
#include "TestSession.h"

using namespace std;
using namespace Chronos;

struct AliasCommandTest {
	AliasCommandTest() : session("player1") {}

	TestSession session;
	AliasCommand aliasCmd;
};


TEST(AliasCommandTest, testAddingAliases) {
	aliasCmd.execute(session, "dw", "drink wine");
    session.SESSION_CHECKWRITTEN("added alias 'dw' -> 'drink wine'.\n");

	aliasCmd.execute(session, "dw", "drink beer");
    session.SESSION_CHECKWRITTEN("changing alias 'dw' from 'drink wine' to 'drink beer'.\n");
}


TEST(AliasCommandTest, testAddShouldNotAddAlias) {
	aliasCmd.execute(session, "alias", "");
    session.SESSION_CHECKWRITTEN("Cannot alias 'alias' or 'unalias'.\n");

	aliasCmd.execute(session, "unalias", "");
    session.SESSION_CHECKWRITTEN("Cannot alias 'alias' or 'unalias'.\n");

	aliasCmd.execute(session, "test", "test");
    session.SESSION_CHECKWRITTEN("Why would you want to alias something to itself?\n");
}

TEST(AliasCommandTest, testAddingMaximumNrOfAliases) {
    int MAX_ALIASES = 100;
    for (int i=0; i<MAX_ALIASES; ++i) {
        string num = Utils::itoa(i);
    	aliasCmd.execute(session, num, "bla");
        session.SESSION_CHECKWRITTEN("added alias '" + num + "' -> 'bla'.\n");
    }
	aliasCmd.execute(session, "max", "eleven");
    session.SESSION_CHECKWRITTEN("Already at maximum number of aliases (100).\n");
}


struct UnAliasCommandTest {
	UnAliasCommandTest() : session("player1") {}

	TestSession session;
	AliasCommand aliasCmd;
	UnAliasCommand unaliasCmd;
};


TEST(UnAliasCommandTest, testShouldUnaliasIfAliasExists) {
	unaliasCmd.execute(session, "1");
	session.SESSION_CHECKWRITTEN("no alias named that way.\n");

	aliasCmd.execute(session, "1", "one");
    session.clear();
	unaliasCmd.execute(session, "1");
	session.SESSION_CHECKWRITTEN("removed alias '1'.\n");
}


struct AliasListCommandTest {
	AliasListCommandTest() : session("player1") {}

	TestSession session;
	AliasListCommand listCmd;
	AliasCommand aliasCmd;
};

TEST(AliasListCommandTest, testShouldListAliases) {
	listCmd.execute(session);
	session.SESSION_CHECKWRITTEN("aliases: (0/100)\n");

	aliasCmd.execute(session, "1", "one");
	aliasCmd.execute(session, "2", "two");
    session.clear();
	listCmd.execute(session);
	session.SESSION_CHECKWRITTEN("aliases: (2/100)\n1   ->   one\n2   ->   two\n");
}

